package com.rsstuan.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;

import javax.cache.Cache;
import javax.cache.CacheFactory;
import javax.cache.CacheManager;

import com.google.appengine.api.memcache.jsr107cache.GCacheFactory;
import com.rsstuan.data.TuanGouWebItem;
import com.rsstuan.storage.data.TuanGouChannelData;
import com.rsstuan.storage.data.TuanGouItemData;
import com.rsstuan.storage.impl.JDOTuanGouItemStorage;
import com.rsstuan.utils.CityUtils;
import com.rsstuan.utils.ItemUtils;

public class ItemService {

    private static ItemService instance = new ItemService();
    
    public static ItemService getInstance() {
        return instance;
    }
    
    private Logger LOG = Logger.getLogger(ChannelService.class.getName());
    
    private Cache cache;
    
    private Properties props = new Properties();
    
    private JDOTuanGouItemStorage itemStorage = new JDOTuanGouItemStorage();
    
    private Map<Long, TuanGouChannelData> channelMap;
   
    private Object sync = new Object();
    
    private ItemService() {
        try {
            props.put(GCacheFactory.EXPIRATION_DELTA, 60 * 60 * 24);
            CacheFactory cacheFactory = CacheManager.getInstance().getCacheFactory();
            cache = cacheFactory.createCache(Collections.emptyMap());
            channelMap = ChannelService.getInstance().getAllChannelsMap();
        }
        catch (Exception e) {
            
        }
    }

    public TuanGouWebItem[] getAllAcitveItemsByCity(String city) {
        if (cache.get("allActiveItems_"+ city) != null) {
            List<TuanGouWebItem> items = new ArrayList<TuanGouWebItem>();
            String itemSeq = (String)cache.get("allActiveItems_" + city);
            String[] idStrs = itemSeq.split(",");
            for (String idStr : idStrs) {
                Long itemId = Long.parseLong(idStr);
                TuanGouWebItem item = getItem(itemId);
                items.add(item);
            }
            if (items != null) 
            	return items.toArray(new TuanGouWebItem[items.size()]);
            else
            	return null;
        } else {
            TuanGouItemData[] items = itemStorage.getActiveItemsByCity(city);
            List<TuanGouWebItem> witems = new ArrayList<TuanGouWebItem>();
            StringBuilder sb = new StringBuilder();
            for (TuanGouItemData item : items) {
                if (ItemUtils.validate(item)) {
                    TuanGouWebItem witem = new TuanGouWebItem(item);
                    witem.setSiteName(ChannelService.getInstance().getChannelName(item.getChannelId()));
                    putIntoCache(witem);
                    witems.add(witem);
                }
            }
            TuanGouWebItem[] webItemArray = witems.toArray(new TuanGouWebItem[witems.size()]);
            if (witems.size() > 0) {
            	String peopleseq = ItemUtils.sortByOrderNumDesc(webItemArray);
            	for (TuanGouWebItem witem : webItemArray) {
            		sb.append(witem.getId()+",");
            	}
            	setOrderSequence(city, "peopleseq", peopleseq);
            	cache.put("allActiveItems_"+city, sb.substring(0, sb.length()-1));
            	
            } 
           return webItemArray;
        }
    }

	
    public List<TuanGouWebItem> getAllAcitveItems() {
        if (cache.get("allActiveItems") != null) {
            List<TuanGouWebItem> items = new ArrayList<TuanGouWebItem>();
            String itemSeq = (String)cache.get("allActiveItems");
            String[] idStrs = itemSeq.split(",");
            for (String idStr : idStrs) {
                Long itemId = Long.parseLong(idStr);
                TuanGouWebItem item = getItem(itemId);
                items.add(item);
            }
            return items;
        } else {
            List<TuanGouItemData> items = itemStorage.getActivateItems();
            List<TuanGouWebItem> witems = new ArrayList<TuanGouWebItem>();
            StringBuilder sb = new StringBuilder();
            for (TuanGouItemData item : items) {
                if (ItemUtils.validate(item)) {
                    TuanGouWebItem witem = new TuanGouWebItem(item);
                    witem.setSiteName(ChannelService.getInstance().getChannelName(item.getChannelId()));
                    sb.append(item.getId()+",");
                    putIntoCache(witem);
                }
            }
            cache.put("allActiveItems", sb.substring(0, sb.length()-1));
            return witems;
        }
    }
    
    public String getOrderSequence(String city, String key) {
    	if (key.equals("priceseq") || key.equals("discountseq") || key.equals("peopleseq"))
    	{
    		String seq = (String)cache.get(key+"_"+city);
    		return seq;
    	}
    	return null;
    }
    
    public void setOrderSequence(String city, String key, String value) {
    	if (key.equals("priceseq") || key.equals("discountseq") || key.equals("peopleseq"))
    	{
    		cache.put(key+"_"+city, value);
    	}
    }
    
    public void updateItems() {
    	for (String city : CityUtils.getAllCities()) {
    		cache.put("allActiveItems_"+ city ,null);
    		TuanGouWebItem[] witems = getAllAcitveItemsByCity(city);
    		String priceseq = ItemUtils.sortByPrice(witems);
    		String discountseq = ItemUtils.sortByDiscount(witems);
    		setOrderSequence(city, "priceseq", priceseq);
    		setOrderSequence(city, "discountseq", discountseq);
    	}	
    }

    /**
     * @param itemId
     * @return
     */
    private TuanGouWebItem getItem(Long itemId) {
        TuanGouWebItem witem = loadFromCache(itemId);
        if (witem != null) {
            return witem;
        } else {
             TuanGouItemData item = itemStorage.getItem(itemId);
            
            if (item != null && ItemUtils.validate(item)) {
                witem = new TuanGouWebItem();
                witem.setSiteName(ChannelService.getInstance().getChannelName(item.getChannelId()));
                putIntoCache(witem);
            }
            return witem;
        }
    }
    
    private TuanGouWebItem loadFromCache(Long itemId) {
        String idStr = itemId.toString();
        if (cache.get(idStr +"_id") != null) {
            TuanGouWebItem item = new TuanGouWebItem();
            item.setId(itemId);
            item.setSiteId((Long)cache.get(idStr+"_siteId"));
            item.setChannelId((Long)cache.get((idStr+"_channelId")));
            item.setImage((String)cache.get((idStr+"_image")));
            item.setTitle((String)cache.get(idStr+"_title"));
            item.setLink((String)cache.get(idStr+"_link"));
            item.setCity((String)cache.get(idStr+"_city"));
            item.setPrice((Double)cache.get(idStr+"_price"));
            item.setOrigPrice((Double)cache.get(idStr+"_origPrice"));
            if (cache.get(idStr+"_orderNum") != null)
               item.setOrderNum(((Integer)cache.get(idStr+"_orderNum")).intValue());
            item.setActivate(((Boolean)cache.get(idStr+"_activate")).booleanValue());
            item.setSiteName((String)cache.get(idStr+"_siteName"));
            return item;
        } else {
            return null;
        }
    }
    
    private void putIntoCache(TuanGouWebItem item) {
        String idStr = item.getId().toString();
        cache.put(idStr+"_id", item.getId());
        cache.put(idStr+"_siteId", item.getSiteId());
        cache.put(idStr+"_channelId", item.getChannelId());
        cache.put(idStr+"_image", item.getImage());
        cache.put(idStr+"_title", item.getTitle());
        cache.put(idStr+"_link", item.getLink());
        cache.put(idStr+"_city", item.getCity());
        cache.put(idStr+"_price", item.getPrice());
        cache.put(idStr+"_origPrice", item.getOrigPrice());
        cache.put(idStr+"_orderNum", Integer.valueOf(item.getOrderNum()));
        cache.put(idStr+"_address", item.getSiteId());
        cache.put(idStr+"_activate", Boolean.valueOf(item.isActivate()));
        cache.put(idStr+"_siteName", item.getSiteName());
        
    }

    /**
     * 
     */
    public void clearCache() {
        this.cache.clear();
        
    }
}
